package com.lagou.edu.util;

import com.alibaba.fastjson.JSON;
import com.lagou.edu.pojo.DataSourceProp;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.io.InputStream;
import java.util.Properties;

public class DataSourceUtil {
    private static JdbcTemplate jdbcTemplate = new JdbcTemplate();

    static {
        try {
            createDefaultDataSource();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void createDefaultDataSource() throws Exception {
        InputStream resourceAsStream = DataSourceUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        dataSource.setDriverClass(properties.getProperty("driverClassName"));
        dataSource.setJdbcUrl(properties.getProperty("url"));
        dataSource.setUser(properties.getProperty("username"));
        dataSource.setPassword(properties.getProperty("password"));
        setJDBCTemplate(dataSource);
        connectZk();
    }

    public static JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    private static void connectZk() throws Exception {
        String zookeeperAddress = "192.168.200.200:2181";

        // 启动zookeeper
        CuratorFramework curatorClient =
                CuratorFrameworkFactory.builder().
                        connectString(zookeeperAddress) //连接地址
                        .connectionTimeoutMs(2000) //连接超时时间
                        .sessionTimeoutMs(10000) //会话超时时间
                        .retryPolicy(new ExponentialBackoffRetry(1000, 3)) //重试策略
                        .namespace("config_center") //命名空间,默认节点
                        .build();
        curatorClient.start();

        // 注册监听
        NodeCache nodeCache = new NodeCache(curatorClient, "/mysql");
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println("config changed");
                ChildData childData = nodeCache.getCurrentData();
                byte[] data = childData.getData();
                DataSourceProp dataSourceProp = JSON.parseObject(data, DataSourceProp.class);
                System.out.println(dataSourceProp);
                ComboPooledDataSource dataSource = new ComboPooledDataSource();
                setDataSource(dataSource, dataSourceProp);
                setJDBCTemplate(dataSource);
            }
        });
        nodeCache.start();
        System.out.println("start to listen to mysql config");
    }

    private static void setJDBCTemplate(ComboPooledDataSource dataSource) {
        ComboPooledDataSource oldDataSource = (ComboPooledDataSource) jdbcTemplate.getDataSource();
        jdbcTemplate.setDataSource(dataSource);
        if (oldDataSource != null) {
            oldDataSource.close();
        }
    }

    private static void setDataSource(ComboPooledDataSource dataSource, DataSourceProp dataSourceConfig) throws PropertyVetoException {
        dataSource.setDriverClass(dataSourceConfig.getDriverClassName());
        dataSource.setJdbcUrl(dataSourceConfig.getUrl());
        dataSource.setUser(dataSourceConfig.getUsername());
        dataSource.setPassword(dataSourceConfig.getPassword());
    }
}
